package com.ruoyi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.OrderType;
import com.ruoyi.common.enums.PaOrderStatus;
import com.ruoyi.common.enums.PxBoxStatus;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.bo.PaOrderItemBo;
import com.ruoyi.system.domain.bo.PxBoxBo;
import com.ruoyi.system.domain.bo.PxBoxItemBo;
import com.ruoyi.system.domain.bo.PxBoxItemDetailBo;
import com.ruoyi.system.domain.vo.PxBoxItemDetailVo;
import com.ruoyi.system.domain.vo.PxBoxItemVo;
import com.ruoyi.system.domain.vo.PxBoxVo;
import com.ruoyi.system.domain.vo.SupplierOrderVo;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.IUserPxBoxService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName UserPxBoxServiceImpl
 * @Description 用户拼装表Service接口
 * @date 2024/7/5 10:31
 * @Version 1.0
 * @Auther: zhangzhenyu
 */
@Service
public class UserPxBoxServiceImpl implements IUserPxBoxService {

    @Autowired
    private PxBoxMapper pxBoxMapper;

    @Autowired
    private PxBoxItemMapper pxBoxItemMapper;

    @Autowired
    private PxBoxItemDetailMapper pxBoxItemDetailMapper;

    @Autowired
    private PxAddrBoxMapper pxAddrBoxMapper;

    @Autowired
    private PaOrderMapper paOrderMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long insertPxBox(PxBoxBo pxBoxBo) {
        PxBox pxBox = new PxBox();
        BeanUtils.copyProperties(pxBoxBo, pxBox);
        pxBox.setStatus(PxBoxStatus.QUOTATION_IN_PROGRESS.getCode());
//        String orderNumber = String.valueOf(new Snowflake(1, 1).nextId());
//        pxBox.setOrderNumber(orderNumber);
        pxBox.setProdName(getProdNames(pxBoxBo));
        pxBoxMapper.insertPxBox(pxBox);
        Long insertPxBoxId = pxBox.getBoxId();

        if (CollectionUtils.isNotEmpty(pxBoxBo.getPxBoxItemList())) {
            //一个拼箱会放多个箱子
            pxBoxBo.getPxBoxItemList().forEach(pxBoxItem -> {
                PxBoxItem pxBoxItem1 = new PxBoxItem();
                BeanUtils.copyProperties(pxBoxItem, pxBoxItem1);
                pxBoxItem1.setBoxId(Long.valueOf(insertPxBoxId));
                pxBoxItemMapper.insertPxBoxItem(pxBoxItem1);
                Long pxBoxItemId = pxBoxItem1.getBoxItemId();
                //每个尺寸的箱子会放多个商品
                List<PxBoxItemDetailBo> pxBoxItemDetailBos = pxBoxItem.getPxBoxItemDetails();
                if (CollectionUtils.isNotEmpty(pxBoxItemDetailBos)) {
                    pxBoxItemDetailBos.forEach(pxBoxItemDetailBo -> {
                        PxBoxItemDetail pxBoxItemDetailBo1 = new PxBoxItemDetail();
                        BeanUtils.copyProperties(pxBoxItemDetailBo, pxBoxItemDetailBo1);
                        pxBoxItemDetailBo1.setBoxItemId(Long.valueOf(pxBoxItemId));
                        pxBoxItemDetailBo1.setBoxId(Long.valueOf(insertPxBoxId));
                        //拼接PxBoxItemDetail对象的prodName 放到一个字符串里
                        pxBoxItemDetailMapper.insertPxBoxItemDetail(pxBoxItemDetailBo1);
                    });
                }
            });
            List<PxAddrBox> pxAddrBoxes = pxBoxBo.getPxAddrBoxes();
            if (CollectionUtils.isNotEmpty(pxAddrBoxes)) {
                pxAddrBoxes.forEach(pxAddrBox -> {
                    PxAddrBox pxAddrBox1 = new PxAddrBox();
                    BeanUtils.copyProperties(pxAddrBox, pxAddrBox1);
                    pxAddrBox1.setBoxId(Long.valueOf(insertPxBoxId));
                    pxAddrBoxMapper.insertPxAddrBox(pxAddrBox1);
                });
            }
        }
        // 如果是代购的拼装还需要更新代购单状态 生产中
        if (OrderType.DGD.getCode().equals(pxBoxBo.getOrderType())) {
            if (pxBoxBo.getOrderId() != null) {
                PaOrder paOrder = new PaOrder();
                paOrder.setOrderId(pxBoxBo.getOrderId());
                paOrder.setStatus(PaOrderStatus.IN_PRODUCTION.getCode());
                paOrderMapper.updatePaOrder(paOrder);
            }
        }
        return insertPxBoxId;
    }

    @Override
    public TableDataInfo<PxBoxVo> selectPxBoxList(PxBoxBo pxBoxBo) {
        PxBox pxBox = new PxBox();
        BeanUtils.copyProperties(pxBoxBo, pxBox);
        PageUtils.startPage();
        List<PxBox> pxBoxes = pxBoxMapper.selectPxBoxList(pxBox);
        PageInfo<PxBox> pageInfo = PageInfo.of(pxBoxes);
        List<PxBoxVo> pxBoxVos = BeanUtil.copyToList(pxBoxes, PxBoxVo.class);
        pxBoxVos.forEach(pxBoxVo -> {
            Long boxId = pxBoxVo.getBoxId();
            PxBoxItem selectedItem =  new PxBoxItem();
            selectedItem.setBoxId(boxId);
            List<PxBoxItem> pxBoxItems = pxBoxItemMapper.selectPxBoxItemList(selectedItem);
            //查询尺寸的箱子
            List<PxBoxItemVo> pxBoxItemVos = BeanUtil.copyToList(pxBoxItems, PxBoxItemVo.class);
            pxBoxVo.setPxBoxItemList(pxBoxItemVos);
            //查询每个尺寸箱子的 多个物品
            pxBoxItemVos.forEach(x -> {
                Long boxItemId = x.getBoxItemId();
                PxBoxItemDetail pxBoxItemDetail = new PxBoxItemDetail();
                pxBoxItemDetail.setBoxItemId(boxItemId);
                List<PxBoxItemDetail> pxBoxItemDetails = pxBoxItemDetailMapper.selectPxBoxItemDetailList(pxBoxItemDetail);
                List<PxBoxItemDetailVo> pxBoxItemDetailVos =  BeanUtil.copyToList(pxBoxItemDetails, PxBoxItemDetailVo.class);
                x.setPxBoxItemDetails(pxBoxItemDetailVos);
            });
            //根据boxId查询地址
            PxAddrBox pxAddrBox = new PxAddrBox();
            pxAddrBox.setBoxId(boxId);
            pxBoxVo.setPxAddrBoxes(pxAddrBoxMapper.selectPxAddrBoxList(pxAddrBox));
        });
        TableDataInfo<PxBoxVo> page = TableDataInfo.build(pxBoxVos);
        page.setTotal(pageInfo.getTotal());
        return page;
    }

    @Override
    public R updatePxBox(PxBoxBo editBo) {
        PxBox pxBoxData = pxBoxMapper.selectPxBoxByBoxId(editBo.getBoxId());
        //如果不是报价中 不允许修改
        if (!pxBoxData.getStatus().equals(PxBoxStatus.QUOTATION_IN_PROGRESS.getCode())) {
            return R.fail("当前拼柜状态不允许修改");
        }
        PxBox pxBox = new PxBox();
        BeanUtils.copyProperties(editBo, pxBox);
        pxBox.setProdName(getProdNames(editBo));
        pxBoxMapper.updatePxBox(pxBox);
        List<PxBoxItemBo> pxBoxItemList = editBo.getPxBoxItemList();
        if (CollectionUtils.isNotEmpty(pxBoxItemList)) {
            pxBoxItemList.forEach(pxBoxItem -> {
                PxBoxItem updateItem = new PxBoxItem();
                BeanUtils.copyProperties(pxBoxItem, updateItem);
                if(pxBoxItem.getBoxItemId() != null) {
                    pxBoxItemMapper.updatePxBoxItem(updateItem);
                } else {
                    updateItem.setBoxId(pxBox.getBoxId());
                    pxBoxItemMapper.insertPxBoxItem(updateItem);
                }
                List<PxBoxItemDetailBo> pxBoxItemDetailBos = pxBoxItem.getPxBoxItemDetails();
                if (CollectionUtils.isNotEmpty(pxBoxItemDetailBos)) {
                    pxBoxItemDetailBos.forEach(pxBoxItemDetailBo -> {
                        PxBoxItemDetail updatePxBoxItemDetail = new PxBoxItemDetail();
                        BeanUtils.copyProperties(pxBoxItemDetailBo, updatePxBoxItemDetail);
                        updatePxBoxItemDetail.setBoxItemId(updateItem.getBoxItemId());
                        updatePxBoxItemDetail.setBoxId(pxBox.getBoxId());
                        if(updatePxBoxItemDetail.getBoxItemDetailId() != null) {
                            pxBoxItemDetailMapper.updatePxBoxItemDetail(updatePxBoxItemDetail);
                        } else {
                            pxBoxItemDetailMapper.insertPxBoxItemDetail(updatePxBoxItemDetail);
                        }
                    });
                }
            });
        }
        List<PxAddrBox> pxAddrBoxes = editBo.getPxAddrBoxes();
        if (CollectionUtils.isNotEmpty(pxAddrBoxes)) {
            pxAddrBoxes.forEach(pxAddrBox -> {
                pxAddrBoxMapper.updatePxAddrBox(pxAddrBox);
            });
        }
        return R.ok(1);
    }

    @Override
    public PxBoxVo selectPxBoxItemById(Long boxId) {
        PxBoxVo pxBoxVo = new PxBoxVo();
        PxBox pxBox = pxBoxMapper.selectPxBoxByBoxId(boxId);
        if (pxBox != null) {
            BeanUtils.copyProperties(pxBox, pxBoxVo);
            //查询每个尺寸箱子的 多个物品
            PxBoxItem pa = new PxBoxItem();
            pa.setBoxId(boxId);
            List<PxBoxItem> pxBoxItems = pxBoxItemMapper.selectPxBoxItemList(pa);
            List<PxBoxItemVo> pxBoxItemVos = BeanUtil.copyToList(pxBoxItems, PxBoxItemVo.class);
            pxBoxVo.setPxBoxItemList(pxBoxItemVos);
            pxBoxItemVos.forEach(param -> {
                Long boxItemId = param.getBoxItemId();
                PxBoxItemDetail pxBoxItemDetail = new PxBoxItemDetail();
                pxBoxItemDetail.setBoxItemId(boxItemId);
                List<PxBoxItemDetail> pxBoxItemDetails = pxBoxItemDetailMapper.selectPxBoxItemDetailList(pxBoxItemDetail);
                List<PxBoxItemDetailVo> pxBoxItemDetailVos =  BeanUtil.copyToList(pxBoxItemDetails, PxBoxItemDetailVo.class);
                param.setPxBoxItemDetails(pxBoxItemDetailVos);
            });
            PxAddrBox pxAddrBox = new PxAddrBox();
            pxAddrBox.setBoxId(boxId);
            pxBoxVo.setPxAddrBoxes(pxAddrBoxMapper.selectPxAddrBoxList(pxAddrBox));
            return pxBoxVo;
        }

        return null;
    }


    private  String getProdNames(PxBoxBo pxBoxBo) {
        String prodNames = null;
        if (CollectionUtils.isNotEmpty(pxBoxBo.getPxBoxItemList())) {
            prodNames = pxBoxBo.getPxBoxItemList().stream()
                    .map(PxBoxItemBo::getPxBoxItemDetails)
                    .flatMap(List::stream)
                    .map(PxBoxItemDetailBo::getProdName)
                    .collect(Collectors.joining(", "));
        }
        return prodNames;
    }
}
